from PyQt5.QtWidgets import QSystemTrayIcon, QApplication, QWidget,QMainWindow, QLabel, QLineEdit, QPushButton, QTextEdit, QSizePolicy, QVBoxLayout
from PyQt5.QtGui import QPalette, QColor,QIcon, QTextCursor
from PyQt5.QtCore import Qt, QThread, pyqtSignal, QMetaType, pyqtSlot
import random
import pygetwindow
import pyautogui
import time
import re
import json
import logging
import pyperclip
import threading
import traceback
import os
import hashlib
import sys
from aip import AipOcr
import gpt
import bang

# 通用文字识别（含位置信息）
baiduOcr = AipOcr('40249967', 'wrH22GfX5GVgd8TZ1FAVTFG6', 'iqAOvDQigHOVhwTWxuFqVibBqwsTmfjX')
def ocr(pathname):
    with open(pathname, 'rb') as f:
        image = f.read()
        results = baiduOcr.general(image)
        return results['words_result']

windows = []
window = None;
mod = 0;
running = False
thread = None
SCREENSHOT_DIR = 'screenshot';
windowPng = None;
contentPng = None;
contentLines = []
kfUID = None;
lastMsgText = None;
lastMsgUID = None;
gpt_key = None; # aidarks-iptifverrujtykxkydmyfrba-655750efb19084b469e4f954
gpt_reply = None;
username = '';
card = {}

# 查找窗口
def findWindow():
    global windows, window, kfUID;
    windows = pygetwindow.getWindowsWithTitle('接待中心')
    if len(windows) == 0:
        raise Exception("找不到客服窗口")
    if len(windows) > 1:
        raise Exception("您打开了多个客服窗口")
    window = windows[0];
    log('[窗口] ' + window.title)

    kfUID = window.title.split(':')[0].replace('-接待中心', '')
    log('[客服UID] ' + kfUID);

# 激活窗口
def activeWindow():
    window.resizeTo(1427, 987)
    window.activate()
    time.sleep(2)

# 窗口截屏
def captureWindow():

    global mod;
    mod = (mod + 1) % 100;

    global windowPng;
    windowPng = SCREENSHOT_DIR + '/' + str(mod) + '.png'

    if not os.path.exists(SCREENSHOT_DIR):
        os.makedirs(SCREENSHOT_DIR)

    screenshot = pyautogui.screenshot(region=(window.left, window.top,  window.width,  window.height))
    screenshot.save(windowPng)

# 对话区域截屏
def captureContent():

    global mod;
    mod = (mod + 1) % 100;

    global contentPng;
    contentPng = SCREENSHOT_DIR + '/' + str(mod) + '.png'

    if not os.path.exists(SCREENSHOT_DIR):
        os.makedirs(SCREENSHOT_DIR)

    screenshot = pyautogui.screenshot(region=(window.left + 314, window.top + 163,  618,  466))
    screenshot.save(contentPng)

# 对话区域文字识别
def detectContent():
    global contentLines, lastMsgText, lastMsgUID, card;
    contentLines = ocr(contentPng)

    lastMsgText = '';
    lastMsgUID = '';
    card = None;

    for i in range(len(contentLines)):
        line = contentLines[ len(contentLines) - i - 1 ]
        words = line['words']
        location = line['location']

        if not '2023-' in words:
            lastMsgText = lastMsgText + words;
            if ('http://' in words) or ('https://' in words):
                log('[卡片] ' + words)
                card = {}
                card['cpX'] = window.left + 314 + location['left'] + location['width'] + 50
                card['cpY'] = window.top + 163 + location['top']  + 5
                pyautogui.click(card['cpX'], card['cpY']);
                time.sleep(0.2)
                card['url'] = pyperclip.paste()
                log('[卡片->完整url] ' + card['url'])
                card['title'] = bang.parseTitle(card['url'])
                log('[卡片->商品标题] ' + card['title'])
        else:
            if kfUID in words:
                lastMsgUID = kfUID
            break;

# 回复消息
def sendReply(content):
    pyautogui.click(window.left + 540, window.top + 795)
    time.sleep(1)

    pyautogui.hotkey('ctrl', 'a')
    time.sleep(0.2)

    pyautogui.press('delete')
    time.sleep(0.2)

    pyperclip.copy(content)
    pyautogui.hotkey('ctrl', 'v')
    time.sleep(0.2)

    pyautogui.hotkey('enter')

# 请求知识库
def requestGpt():

    print('[ChatId] ' + username)

    global gpt_reply;
    if card:
        gpt_reply = gpt.request(gpt_key, card['title'], username);
    else:
        gpt_reply = gpt.request(gpt_key, lastMsgText, username);

# 输出日志
def log(content):
    thread.log_signal.emit(content)

# 获取用户名
def getUsername():
    global username;
    username = '';
    pyautogui.click(window.left + 174, window.top + 289, button='right')
    time.sleep(0.2)
    pyautogui.click(window.left + 283, window.top + 332)
    time.sleep(0.2)
    username = pyperclip.paste()
    log('[用户] ' + username)

# 重新排序
def reOrder():
    pyautogui.click(window.left + 240, window.top + 246)
    time.sleep(0.2)

    pyautogui.click(window.left + 291, window.top + 347)

    time.sleep(0.2)

    pyautogui.click(window.left + 240, window.top + 246)
    time.sleep(0.2)

    pyautogui.click(window.left + 291, window.top + 377)
    time.sleep(0.2)

class WorkerThread(QThread):

    log_signal = pyqtSignal(str)

    def run(self):
        while True:
            try:
                time.sleep(10)
                if not running: continue;
                findWindow()
                activeWindow()
                reOrder()
                getUsername()
                captureWindow()
                captureContent()
                detectContent()

                if lastMsgUID == kfUID:
                    log('[消息状态] 已回复')
                else:
                    log('[消息状态] 待回复')
                    requestGpt()
                    log('[知识库] ' + gpt_reply)
                    sendReply(gpt_reply)

            except Exception as e:
                print(e)

class MyWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("千牛AI助手 - v2023.11.28")
        self.setFixedWidth(500)
        self.setMinimumHeight(700)

        # 图标
        icon = QIcon("logo.jpg")
        self.setWindowIcon(icon)

        # 第一个输入框
        self.key_input = QLineEdit()
        self.key_input.setFixedHeight(38)
        self.key_input.setStyleSheet("border: 1px solid #dedede;  padding: 0 10px; font-size: 16px;")
        self.key_input.setText("")
        self.key_input.setPlaceholderText('密钥')

        # 第二个输入框
        self.key_input2 = QLineEdit()
        self.key_input2.setFixedHeight(38)
        self.key_input2.setStyleSheet("border: 1px solid #dedede;  padding: 0 10px; font-size: 16px;")
        self.key_input2.setText("")
        self.key_input2.setPlaceholderText('APP_ID')

        # 开始按钮
        self.run_button = QPushButton("开始")
        self.run_button.setFixedHeight(40)
        self.run_button.setCursor(Qt.PointingHandCursor)
        self.run_button.clicked.connect(self.runButtonClick)
        self.run_button.setHidden(False)

        # 停止按钮
        self.stop_button = QPushButton("停止")
        self.stop_button.setFixedHeight(40)
        self.stop_button.setCursor(Qt.PointingHandCursor)
        self.stop_button.clicked.connect(self.stopButtonClick)
        self.stop_button.setHidden(True)

        # 日志区域
        self.output_text = QTextEdit()

        size_policy = self.output_text.sizePolicy()
        size_policy.setVerticalPolicy(QSizePolicy.Expanding)
        self.output_text.setSizePolicy(size_policy)

        # self.output_text.setFixedHeight(200)

        self.output_text.setStyleSheet("border: 1px solid #dedede;  padding: 10px; line-height: 32px; font-size: 16px;")

        global output_text
        output_text = self.output_text

        # 垂直布局
        layout = QVBoxLayout()
        layout.addWidget(self.key_input)
        layout.addWidget(self.key_input2)
        layout.addWidget(self.run_button)
        layout.addWidget(self.stop_button)
        layout.addWidget(self.output_text)

        # 居中显示
        central_widget = QWidget()
        central_widget.setLayout(layout)
        self.setCentralWidget(central_widget)

        # 开启子线程
        global thread;
        thread = WorkerThread()
        thread.log_signal.connect(self.logEvent)
        thread.start()

    # 日志输出事件
    def logEvent(self, text):
        self.output_text.append(text)

    # 开始按钮被点击
    def runButtonClick(self):

        global running, gpt_key;

        key1 = self.key_input.text()
        key2 = self.key_input2.text()

        if not key1:
            self.output_text.append("*** 请输入密钥 ***")
            return;

        if not key2:
            self.output_text.append("*** 请输入APP_ID ***")
            return;

        gpt_key = key1 + '-' + key2;
        running = True
        self.run_button.setHidden(True)
        self.stop_button.setHidden(False)

    # 停止按钮被点击
    def stopButtonClick(self):
        global running;
        running = False
        self.run_button.setHidden(False)
        self.stop_button.setHidden(True)

if __name__ == "__main__":
     app = QApplication(sys.argv)
     win = MyWindow()
     win.show()
     sys.exit(app.exec_())